﻿define(function(require, exports){

  'use strict';
  var $ = require('seajs/jquery.min');
  require('seajs/plugs/jquery.md5')($); 
  var _const = require('seajs/fn/fnConst');
  var fnUtils = require('seajs/fn/fnUtils');
  var fnSocketHandler = require('seajs/fn/fnSocketHandler');
  var FnErrorHandler = require('seajs/fn/fnErrorHandler');
  var Tasks = require('seajs/fn/fnTasks');
  var fnRtpSocket = require('seajs/fn/fnRtpSocket');
  var fnModal = require('seajs/fn/fnModal');
  var fnData = require('seajs/fn/fnData');
  var uname;//拍传全局
  var heartBeatTimeoutId, lbsTimeoutId, taskId,initGid;

  var options={
    enableHighAccuracy: true, 
    maximumAge: 1000
  }

  var _sendMsg = function(ws, cmd, rsp, body){
    if(ws){
      var msg = {
        cmd: cmd,
        v: _const.WS.MSG.V,
        msgid: fnUtils.getUnixTime(),
        rsp: rsp,
        body: body
      }
      var rlt = JSON.stringify(msg);
      if(ws.readyState == WebSocket.OPEN){
        console.log('********** ws.msg start ***********');
        console.log(rlt);
        console.log('********** ws.msg end ***********');
        ws.send(rlt);
      }
      // else{
      //   onError({err: 'webSocket UNOPEN'});
      // }
    }
    // else{
    //   onError({err: 'webSocket 未创建'});
    // }
  }

  var sendHeartBeat = function(container){
     _sendMsg(container.ws, _const.WS.EVENT_TYPE.HEART_BEAT.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getHeartBeatMsg(container.cmpid, container.uid, container.key));
  }
  var heartBeat = function(container){
    heartBeatTimeoutId = setTimeout(function(){
      sendHeartBeat(container);
      heartBeat(container);
    }, _const.WS.HEART_BEAT_CONFIG.TIME);
  }
  /**********************************************************
  ************************ Websocket ************************
  ***********************************************************/

  var webSocket = function(cmpid, uid, pwd, key){
    this.ws = undefined;
    this.cmpid = cmpid;
    this.uid = uid;
    this.pwd = pwd;
    this.key = key;
    this.cid = undefined;
    this.sid = undefined;

    this.currentId=undefined;
    this.isInitFlag = false;
    this.currentGid = undefined;

    this.isNormalClose = false;
  
    this.lng = undefined;
    this.lat = undefined;
    this.slidebar = undefined;
    this.showMarkerMap = undefined;
    this.fnSocketHandler = fnSocketHandler;
    this.tasks = undefined;

    //rpt相关参数
    this.rtpWs = undefined;
    this.init();
  }
  webSocket.prototype.setShowMarkerMap = function(_showMarkerMap){
    this.showMarkerMap = _showMarkerMap;
  }
  webSocket.prototype.setSlidebar = function(_slidebar){
    this.slidebar = _slidebar;
    this.rtpWs.setSlidebar(_slidebar);
  }
  webSocket.prototype.init = function(){
    var self = this;
    if(self.cmpid && self.uid && self.pwd){
      self.tasks = new Tasks(self);
      self.rtpWs = new fnRtpSocket(self.uid);
      self.rtpWsInit(function(){
        
      });
      self.wsInit();
    }
  }
  webSocket.prototype.rtpWsInit = function(onSuccess){
    var self = this;
    self.rtpWs.init(onSuccess);
  }

  webSocket.prototype.wsInit = function(){
    var self = this;
    self.ws = new WebSocket('ws://' 
        + _const.WS.CONFIG.HOST + ':' 
        + _const.WS.CONFIG.PORT + '/' 
        + _const.WS.CONFIG.PATH);
    self.onopen();
    self.onclose();
    self.onerror();
  }

  webSocket.prototype.onopen = function(){
    if(this.ws){
      var container = this;
      var _cmpid = this.cmpid;
      var _uid = this.uid;
      var _pwd = this.pwd;
      var _ws = this.ws;
      this.ws.onopen = function(){
        $('#dangerModal').modal('hide');
        container.onmessage();
        _sendMsg(container.ws, _const.WS.EVENT_TYPE.ACCESS.REQ, 
          _const.WS.MSG.RSP_NEED, fnSocketHandler.getAccessMsg(container.cmpid, container.uid, container.pwd));
        clearInterval(heartBeatTimeoutId);
        clearInterval(lbsTimeoutId);
        container.rtpWs.exitRtp();
      }
    }else{
      throw new Exception('webSocket 未创建');
    }
  }
//
  webSocket.prototype.onmessage = function(){
    if(this.ws){
      var container = this;
      container.ws.onmessage = function(event){
        var msg = JSON.parse(event.data);
        if(msg.cmd === undefined){
          return;
        }
        console.log('========== onmessage() start =========');
        console.log(JSON.stringify(msg));
        console.log('========== onmessage() end =========');
        if(msg.body){
          switch(msg.cmd){
            // 8001 
            case _const.WS.EVENT_TYPE.ACCESS.RES:
              fnSocketHandler.accessHandler(container, msg);
              sendHeartBeat(container);
              heartBeat(container);
              container.pushLbs();
              break;
            // 8002
            case _const.WS.EVENT_TYPE.HEART_BEAT.RES:
              fnSocketHandler.heartBeatHandler(container, msg);
              break;
            // 8003
            case _const.WS.EVENT_TYPE.IN_CHANNEL.RES:
              if(msg.body.type==_const.PTT_TYPE.TALKING){
                  initGid=msg.body.gid;
              }
              fnSocketHandler.inChannelHandler(container, msg);
              break;
            // 8004
            case _const.WS.EVENT_TYPE.OUT_CHANNEL.RES:
              fnSocketHandler.outChannelHandler(container, msg);
              break;
             // 8005
            case _const.WS.EVENT_TYPE.VIDEO_SINGLE_CALL_HANG_UP.RES:
              fnSocketHandler.videoSingleCallHangUpHandler(container, msg);
              break;
            // 6 单呼挂断通知
            case _const.WS.EVENT_TYPE._VIDEO_SINGLE_CALL_HANG_UP.RES:
              fnSocketHandler._videoSingleCallHangUpHandler(container, msg);
              break;
            // 8007
            case _const.WS.EVENT_TYPE.VIDEO_SINGLE_CALL.RES:
              fnSocketHandler.videoSingleCallHandler(container, msg);
              break;
            // 8013 断线重连，恢复对讲状态
            case _const.WS.EVENT_TYPE._STASH_POP.RES:
              if(msg.body.type==_const.PTT_TYPE.TALKING){
                initGid=msg.body.gid;
              }
              fnSocketHandler._stashPopHandler(container, msg);
              clearInterval(heartBeatTimeoutId);
              clearInterval(lbsTimeoutId);
              sendHeartBeat(container);
              heartBeat(container);  
              container.pushLbs();
              break;
            // 8014
            case _const.WS.EVENT_TYPE.PULL_LBS.RES:
              fnSocketHandler.pullLbsHandler(container, msg);
              break;
            // 8016
            case _const.WS.EVENT_TYPE.BOARDCAST.RES:
              fnSocketHandler.boardcastHandler(container, msg);
              break;
            // 8018
            case _const.WS.EVENT_TYPE.BOARDCAST_HANG_UP.RES:
              fnSocketHandler.boardcastHangUpHandler(container, msg);
              break;
            // 8020
            case _const.WS.EVENT_TYPE.TEMPORARY_TALK.RES:
              fnSocketHandler.temporaryTalkHandler(container, msg);
              break;
            //8022
            case _const.WS.EVENT_TYPE.TEMPORARY_TALK_HANG_UP.RES:
              fnSocketHandler.temporaryTalkHangUpHandler(container, msg);
              break;
            // 24 退出媒体通知
            case _const.WS.EVENT_TYPE.EXIT_ALL.RES:
              fnSocketHandler.exitAllHandler(container, msg);
              break;
            case _const.WS.EVENT_TYPE.TEMPORARY_TALK_ADD.RES:
              fnSocketHandler.temporaryTalkAddHandler(container, msg);
              break;
            // 9001
            case _const.WS.EVENT_TYPE.ON_LINE.RES:
              fnSocketHandler.onLineHandler(container, msg);
              break;
            //9002
            case _const.WS.EVENT_TYPE.OFF_LINE.RES:
              fnSocketHandler.offLineHandler(container, msg);
              break;
            //9003
            case _const.WS.EVENT_TYPE.CUT_SET.RES:
              fnSocketHandler.cutSetHandler(container, msg);
              break; 
            //10101 管理台信令
            case _const.WS.EVENT_TYPE.ADMIN_USER_DISABLE.RES:
              fnSocketHandler.adminUserDisableHandler(container, msg);
              break;
            //10102
            case _const.WS.EVENT_TYPE.ADMIN_USER_ENABLE.RES:
              fnSocketHandler.adminUserEnableHandler(container, msg);
              break;
            //10103
            case _const.WS.EVENT_TYPE.ADMIN_USER_DELETE.RES:
              fnSocketHandler.adminUserDelHandler(container, msg);
              break;
            //10104 
            case _const.WS.EVENT_TYPE.ADMIN_USER_PWD_RESET.RES:
              fnSocketHandler.adminUserPwdResetHandler(container, msg);
              break;
            //10201
            case _const.WS.EVENT_TYPE.ADMIN_GROUP_DISABLE.RES:
              fnSocketHandler.adminGroupDisableHandler(container, msg);
              break;
            //10202
            case _const.WS.EVENT_TYPE.ADMIN_GROUP_ENABLE.RES:
              fnSocketHandler.adminGroupEnableHandler(container, msg);
              break;
            //10203
            case _const.WS.EVENT_TYPE.ADMIN_GROUP_DELETE.RES:
              fnSocketHandler.adminGroupDelHandler(container, msg);
              break;
            //10301
            case _const.WS.EVENT_TYPE.ADMIN_GROUP_USER_LEAVE.RES:
              fnSocketHandler.adminGroupUserLeave(container, msg);
              break;
            //10302 用户添加群组
            case _const.WS.EVENT_TYPE.ADMIN_GROUP_USER_JOIN.RES:
              fnSocketHandler.adminGroupUserJoin(container, msg);
              break;
            //9100 拍传
            case _const.WS.EVENT_TYPE.PUSH_MSG.RES:
              fnSocketHandler.pushUploadPhotoMessage(container, msg,uname);
              break;
            default:
              fnSocketHandler.otherHandler(msg);
          }
        }
      }
    } else {
      throw new Exception('webSocket 未创建');
    }

  }

  webSocket.prototype.close = function(){
    if(this.ws){
      this.isNormalClose = true;
      this.ws.close();
    }
  }

  webSocket.prototype.onclose = function(){
    var self = this;
    self.ws.onclose = function(){
      if($('#success_bar_info').html()=='密码修改成功，3S后跳转至登录界面!'){
        self.isNormalClose=true;
      }
      if(!self.isNormalClose){
        $('.danger-bar-info').html('网络异常,重连中...');
        $('#dangerModal').modal('show');
        if(self.tasks.currentId !== undefined){
          self.tasks.remove(self.tasks.currentId);
        }
        self.wsInit();
      }
    };
  }

  webSocket.prototype.onerror = function(){
    var self = this;
    this.ws.onerror = function(e){}
  }

  webSocket.prototype.sendMsg = _sendMsg;

  // webSocket.prototype.joinDefaultGroup = function(){
  //   if(this.slidebar !== undefined && this.slidebar.defaultGroup){
  //     this.slidebar.checkR(this.slidebar.defaultGroup);
  //     this.slidebar.checkGMSM(this.slidebar.defaultGroup);
  //     this.slidebar.groupRadioOnChanged();
  //     _sendMsg(this.ws, _const.WS.EVENT_TYPE.IN_CHANNEL.REQ, _const.WS.MSG.RSP_NEED, 
  //       fnSocketHandler.getInChannelMsg(this.cmpid, this.uid, this.slidebar.defaultGroup, _const.PTT_TYPE.TALKING));
  //   }
  // }

  webSocket.prototype.joinGroup = function(gid, type){
    _sendMsg(this.ws, _const.WS.EVENT_TYPE.IN_CHANNEL.REQ, _const.WS.MSG.RSP_NEED, 
      fnSocketHandler.getInChannelMsg(this.cmpid, this.uid, parseInt(gid), type));
  }

  webSocket.prototype.joinBeforeGroup = function(){
    this.currentGid = this.slidebar.getJoinedGroup();
    if(this.currentGid){
      if(!this.isInitFlag){
        this.slidebar.checkR(this.slidebar.defaultGroup);
        this.isInitFlag = true;
      }else{
        this.slidebar.setTalkStatus(1,
            fnUtils.contentFormat(this.slidebar.groupMap.get(this.currentGid).groupName, 6, 2));
        this.joinGroup(this.currentGid, _const.PTT_TYPE.TALKING);
      }
    }
  }

  webSocket.prototype.exitGroup = function(){
    _sendMsg(this.ws, _const.WS.EVENT_TYPE.OUT_CHANNEL.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getOutChannelMsg(this.cmpid, this.uid));
  }

  webSocket.prototype.singleCall = function(eduid, gid){
    if(this.cmpid && this.uid && eduid){
      _sendMsg(this.ws, _const.WS.EVENT_TYPE.VIDEO_SINGLE_CALL.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getVideoSingleCallMsg(this.cmpid, this.uid, eduid, gid));
    }
  };

  webSocket.prototype.singleCallHangUp = function(cid, sid, gid){
    if(cid && sid && gid){
       _sendMsg(this.ws, _const.WS.EVENT_TYPE.VIDEO_SINGLE_CALL_HANG_UP.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getVideoSingleCallHangUpMsg(cid, sid, this.uid, gid));
    }
  }

  webSocket.prototype._singleCallHangUp = function(cid, sid){
    if(cid && sid){
      _sendMsg(this.ws, _const.WS.EVENT_TYPE._VIDEO_SINGLE_CALL_HANG_UP.REQ, _const.WS.MSG.RSP_NOT_NEED, 
        fnSocketHandler.get_videoSingleCallHangUpMsg(cid, sid, 0));
    }
  }

  webSocket.prototype.boardcast = function(groupId){
    if(groupId){
      _sendMsg(this.ws, _const.WS.EVENT_TYPE.BOARDCAST.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getBoardcastMsg(this.cmpid, this.uid, parseInt(groupId)));
      this.slidebar.setTalkStatus(2,'广播中')
      //$('#active-group').html('当前状态');
      //$('#main_bottom_left_voice_obj1').html('广播中');
    }
  }

  webSocket.prototype.boardCastHangUp = function(cid, sid, gid){
    if(cid && sid && gid){
       _sendMsg(this.ws, _const.WS.EVENT_TYPE.BOARDCAST_HANG_UP.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getBoardcastHangUpMsg(cid, sid, this.uid, gid));
    }
  }

  webSocket.prototype.temporaryTalk = function(groupId){
    this.tasks.currentId = groupId;
    _sendMsg(this.ws, _const.WS.EVENT_TYPE.TEMPORARY_TALK.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getTemporaryTalkMsg(this.cmpid, this.uid, parseInt(groupId)));
  }

  webSocket.prototype.temporaryTalkAdd = function(groupId, uids){
    _sendMsg(this.ws, _const.WS.EVENT_TYPE.TEMPORARY_TALK_ADD.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getTemporaryTalkAddMsg(this.cmpid, this.uid, parseInt(groupId), uids));
  }
  webSocket.prototype.overTalkSite=function(map){
    AMap.plugin(['AMap.Geolocation'],function(){
      var geolocation=new AMap.Geolocation({
        enableHighAccuracy:true,
        covert:true,
        showButton:false,
        panToLocation:true,
        showCircle:false,
        showMarker:false,
        timeout:60000
      })
      geolocation.getCurrentPosition();//获取当前位置
      map.addControl(geolocation);
      map.setZoom(15);
    })

  }
  webSocket.prototype.temporaryTalkHangUp = function(cid, sid, gid){
    if(cid && sid && gid){
      _sendMsg(this.ws, _const.WS.EVENT_TYPE.TEMPORARY_TALK_HANG_UP.REQ, _const.WS.MSG.RSP_NEED, 
        fnSocketHandler.getTemporaryTalkHangUpMsg(cid, sid, this.uid, gid));
    }
  }

  webSocket.prototype.pushLbs = function(){
    var self = this;
    if(navigator.geolocation){
       //浏览器支持geolocation
       navigator.geolocation.getCurrentPosition(
        function(position){
          //经度
          self.lng = position.coords.longitude;
          //纬度
          self.lat = position.coords.latitude;
          lbsTimeoutId = setTimeout(function(){
            _sendMsg(self.ws, _const.WS.EVENT_TYPE.PUSH_LBS.REQ, _const.WS.MSG.RSP_NOT_NEED, 
              fnSocketHandler.getPushLbsMsg(self.cmpid, self.uid, self.lng, self.lat));
            self.pushLbs();
          }, _const.WS.PUSH_LBS_CONFIG.TIME);
        },
        function(error){
          clearInterval(lbsTimeoutId);
          console.log(error);
           switch(error.code){
             case 1:
             console.log("位置服务被拒绝");
             break;
             case 2:
             console.log("暂时获取不到位置信息");
             break;
             case 3:
             console.log("获取信息超时");
             break;
             case 4:
             console.log("未知错误");
             break;
           }
        },options);
    }
  }
  return webSocket;
});